<?php

namespace SLN0002\DAO;

/**
 * 记账凭证助手类，主要用于辅助自动生成凭证
 * 本助手类的主要目的是：
 * 在内存中创建Array数据结构，给VoucherDAO::addVoucher使用
 * 
 * 从面向对象设计的角度，应该写几个class来表达对应的数据结构，
 * 但是因为分录附加项本身是动态的，所以这里就偷懒索性全部用Array，
 * 从设计的角度来说，不是好的设计，失去了强类型的好处
 * 
 * 使用方法：
 * $builder = new VoucherBuilder();
 * 
 * $voucher = $builder->buildVoucherHeader(...);
 * 
 * foreach(......){
 *  // 创建分录
 *  $item = $builder->buildVoucherDetailItem(...);
 *  // 创建分录附加项
 *  $itemEx = $builder->buildVoucherDetailItemEx(...);
 *  // 合并成完整的分录
 *  $builder->combineItemAndItemEx($item, $itemEx);
 * 
 *  // 把完整分录加入到凭证中
 *  $builder->addItemToVoucher($voucher, $item);
 * }
 * 
 * @author PSI
 * @copyright 2015 - present
 * @license GPL v3
 */
class VoucherBuilder
{
  /**
   * 创建凭证主表数据结构
   */
  public function buildVoucherHeader(
    $userId,
    $dataOrg,
    $companyId,
    $wordId,
    $voucherDT,
    $chargeUserId,
    $cashUserId,
    $bizUserId,
    $billNumber,
  ) {
    $result = [];

    // 当前凭证的创建人
    $result["loginUserId"] = $userId;

    // 当前凭证的创建人的数据域
    $result["dataOrg"] = $dataOrg;

    // 当前凭证所属核算组织机构
    $result["orgId"] = $companyId;

    // 凭证字id: 表t_sln0002_ct_voucher_word的id字段
    // -1 表示不使用凭证字
    $result["wordId"] = $wordId;

    // 凭证日期
    $result["voucherDT"] = $voucherDT;

    // 主管会计
    $result["chargeUserId"] = $chargeUserId;

    // 出纳
    $result["cashUserId"] = $cashUserId;

    // 业务责任人
    $result["bizUserId"] = $bizUserId;

    // 原始凭证数
    $result["billNumber"] = $billNumber;

    // 忽略检查借贷是否相等，因为这是用于自动创建凭证，借贷相等由后台程序本身来保证 
    $result["ignoreBalance"] = 1;

    // 系统自动生成的凭证
    $result["createdBy"] = 1;

    // 分录
    $result["items"] = [];

    return $result;
  }

  /**
   * 创建凭证分录数据结构
   */
  public function buildVoucherDetailItem($subjectCode, $money, $dbOrCr, $summary)
  {
    $result = [];

    // 会计科目码
    $result["subjectCode"] = $subjectCode;

    // 借贷金额
    if ($dbOrCr == "db") {
      $result["debit"] = $money;
      $result["credit"] = null;
    } else {
      $result["debit"] = null;
      $result["credit"] = $money;
    }

    // 摘要
    $result["summary"] = $summary;

    $result["itemEx"] = [];

    return $result;
  }

  /**
   * 创建分录附加项
   */
  public function buildVoucherDetailItemEx($colId, $value, $codeId, $codeValue, $nameValue)
  {
    $result = [];

    // 分录附加项的id，对应于表t_acc_fmt_cols的id自动的值
    $result["colId"] = $colId;

    // 分录附加项的值
    $result["value"] = $value;

    // 当分录附加项是码表录入的时候，对应的码表的id
    $result["codeId"] = $codeId;

    // 当分录附加项是码表录入的时候，对应的码表的code
    $result["codeValue"] = $codeValue;

    // 当分录附加项是码表录入的时候，对应的码表的name
    $result["nameValue"] = $nameValue;

    return $result;
  }

  /**
   * 把分录附加项和分录关联起来
   */
  public function combineItemAndItemEx(&$item, &$itemEx)
  {
    $item["itemEx"] = $itemEx;
  }

  /**
   * 把分录附加到凭证
   */
  public function addItemToVoucher(&$voucher, &$item)
  {
    $items = &$voucher["items"];
    $items[] = $item;
  }
}
